home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / video / scrollmon / scrollmon.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  13.7 KB  |  499 lines

  1. /*
  2.  * Copyright (C) 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /*----------------------------------------------------------------
  19.  * 
  20.  *  scrollmon - live video titling
  21.  *         
  22.  *  
  23.  *  10.93  John Magdziarz, Silicon Graphics, Inc.
  24.  *         Last edit  04.07.94
  25.  * 
  26.  *----------------------------------------------------------------*/
  27. char ident[] = "@(#)scrollmon Version 1.1, John Magdziarz 10.93";
  28.  
  29. #include <scrollmon.h>
  30.  
  31. extern void initVideo(Widget);
  32. extern Widget toplevel;
  33.  
  34. extern void scrollCreds(XtPointer w, ulong *id);
  35. extern "C" {
  36. long *longimagedata(char *);
  37. int sizeofimage(char *, int *, int *);
  38. }
  39. extern createInterface(int *, char **);
  40.  
  41. extern resources appResources;
  42. extern XtAppContext app_context;
  43. extern Widget glw;
  44.  
  45. void grabTextBlocks(Widget, XtPointer , XtPointer);
  46. static void udpateStatBar(short);
  47.  
  48. PerfCalc *timerPerf = new PerfCalc("timer");
  49. PerfCalc *frameRatePerf = new PerfCalc("frameRate");
  50. CredSection *credSects[100];
  51. int FRAMETIME = FALSE;
  52. int direction = 1;
  53. FColors fcolors;
  54. long bgcol;
  55. int swapCnt = 0;
  56. int dropped;
  57. int refreshRate = 60;
  58. int refreshIntvl;
  59. Boolean gfxSetupComplete = False;
  60. Boolean credMotion = True;
  61. Boolean videoBg = True;
  62. Boolean refresh = False;
  63. Boolean restart = False;
  64.  
  65. ulong *tmpbuf;
  66.  
  67. enum TokenType { FONTCMD, COLORCMD, IMAGECMD, LMARGINCMD, RMARGINCMD, 
  68.                  BGCOLCMD, toklen };
  69. const int TOKENCNT = toklen + 1;
  70.  
  71.  
  72. typedef struct TokenStruct {
  73.     char *name;
  74.     enum TokenType token;
  75. };
  76.  
  77. TokenStruct tokens[] = {
  78.     {"FONT", FONTCMD},
  79.     {"COLOR", COLORCMD},  
  80.     {"IMAGE", IMAGECMD},
  81.     {"LMARGIN", LMARGINCMD},
  82.     {"RMARGIN", RMARGINCMD}
  83. };
  84.  
  85.  
  86.  
  87.  
  88. static void
  89. setProcessPriority() 
  90. {
  91.   int result;
  92.   pid_t pid;
  93.  
  94.     // switch priority to super-user
  95.     setreuid(geteuid(), geteuid());
  96.     setregid(getegid(), getegid());
  97.     
  98.     result = prctl(PR_RESIDENT);
  99.     if (result == -1)
  100.       fprintf(stderr, "unable to insure that process is memory-resident.\n");
  101.  
  102.     pid = getpid();
  103.     result = schedctl(NDPRI, pid, NDPHIMIN);
  104.     if (result == -1)
  105.       fprintf(stderr, "unable to set process priority. need to run as root.\n");
  106.     
  107.     // resume our previous identity
  108.     setreuid(getuid(), getuid());
  109.     setregid(getgid(), getgid());
  110. }    
  111.  
  112.  
  113. int
  114. determineJustification(CredSection *curSect, char c, ulong strWidth)
  115. {
  116.   switch (c) {
  117.     case 'C':
  118.       return(appResources.winW / 2 - strWidth / 2);
  119.     case 'R':
  120.       return(appResources.winW - curSect->rMargin - strWidth);
  121.     case 'L':
  122.       return(curSect->lMargin);
  123.     default:
  124.       cout << "error in justification setting." << endl;
  125.   }   
  126. }
  127.  
  128.  
  129.  
  130. void
  131. determineRefreshRate()
  132. {
  133.   switch(getmonitor()) {
  134.     case HZ50:
  135.       refreshRate = 50;
  136.       break;
  137.     case HZ60:
  138.       refreshRate = 60;
  139.       break;
  140.     case HZ72:
  141.       refreshRate = 72;
  142.       break;
  143.     default:
  144.       cout << "current refresh rate not supported" << endl;
  145.       exit(0);
  146.   }
  147.   if (refreshRate != 50 && refreshRate != 60) {
  148.       cout << endl;
  149.       cout << "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl;
  150.       cout << "To get the update rate of the graphics to match the update rate" << endl;
  151.       cout << "of your video standard you should set your monitor with setmon to" << endl;
  152.       cout << "60HZ for NTSC or 50HZ for PAL.  Additionally you can use the" << endl;
  153.       cout << "-F option to setmon to set framelocking." << endl;
  154.   }
  155.   cout << endl;
  156.   cout << "Currently your monitor refresh rate is " << refreshRate << "HZ" << endl;
  157.   div_t rr = div(refreshRate,  appResources.fps);
  158.   if (rr.rem != 0) {
  159.     cout << "You have selected " << appResources.fps << "fps" << endl;
  160.     cout << "which is not possible. Rounding down to the next integral" << endl;
  161.     cout << "multiple of the refresh rate: ";
  162.     appResources.fps = refreshRate / (rr.quot + 1);
  163.     cout << appResources.fps << "fps" << endl; 
  164.     cout << "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << endl;
  165.   }   
  166. }
  167.  
  168.  
  169. void
  170. setRefreshFlag(Widget, XtPointer , XtPointer)
  171. {
  172.     refresh = True;
  173. }
  174.  
  175.  
  176. void
  177. grabTextBlocks(Widget, XtPointer , XtPointer)
  178. {     
  179.   short x = 0;
  180.   short y = 300;
  181.   CredFont *credFont;
  182.  
  183.   if (!restart) {        
  184.       determineRefreshRate();
  185.   }
  186.  
  187. //  XtRemoveCallback(glw, GlxNexposeCallback, grabTextBlocks, 0);
  188.   readsource(SRC_BACK);
  189.   cpack(bgcol);
  190.   clear();
  191.   swapbuffers();
  192.   for ( int j = 0; j < CredSection::credSectCnt; j++ ) {
  193.    if (credSects[j]->credType == FontTypeId) {
  194.     credFont = (CredFont *)credSects[j];
  195.     credFont->loadFontEnv();
  196.     for ( int k = 0; k < credFont->credCnt; k++) {
  197.       cpack(bgcol);
  198.       clear();
  199.       wfm_cpack(credFont->fontColor);
  200.       wfm_cmov2i( x, y );
  201.       credFont->image[k].width = (int)wfm_strwidth(credFont->getStr(k));
  202.       credFont->image[k].height = credFont->size;
  203.       credFont->image[k].xpos = determineJustification(credFont, 
  204.                                                credFont->fontJust[0], 
  205.                                            credFont->image[k].width);
  206.       wfm_charstr( credFont->getStr(k) );
  207.       credFont->image[k].imgBuf = new ulong[(credFont->image[k].width + 1) *
  208.                                          (credFont->image[k].height + 1)];
  209.       short x1 = x;
  210.       short y1 = (short)(y - credFont->finfo.yorig);
  211.       short x2 = (short)(x1 + credFont->image[k].width);
  212.       if (x2 > appResources.winW)
  213.         x2 = appResources.winW;
  214.       short y2 = (short)(y1 + credFont->image[k].height);
  215.       lrectread(x1, y1, x2, y2, credFont->image[k].imgBuf);
  216.      }
  217.     }
  218.    }
  219.   readsource(SRC_FRONT);
  220.   refreshIntvl = (int)(refreshRate / appResources.fps);
  221.   swapinterval(refreshIntvl);
  222.   frameRatePerf->startTiming();
  223.   gfxSetupComplete = True;
  224.   refresh = True;
  225. }
  226.  
  227.  
  228.  
  229. int
  230. getToken(char *directive)
  231. {
  232.   for (int i = 0; i < TOKENCNT; i++) 
  233.     if (!strcmp(directive, tokens[i].name)) {
  234.       return(tokens[i].token);
  235.     }
  236. }
  237.  
  238.  
  239. void 
  240. readImage(char *filename, int *xsize, int *ysize, ulong **buf)
  241. {
  242.     *buf = (ulong *)longimagedata(filename);
  243.     sizeofimage(filename, xsize, ysize);
  244. }
  245.  
  246.   
  247. void 
  248. readCreditsFile()
  249. {
  250.     const int lineSize = 255;
  251.     char fFamily[80];
  252.     char lineStr[lineSize];
  253.     int fSize = 12;
  254.     char fCname[80];
  255.     long fColor;
  256.     char fJust[80];
  257.     float fAngle = 0;
  258.     float fSpacing = 1;
  259.     char directive[lineSize];
  260.     static int lmargin = (int)(appResources.winW * 0.15);
  261.     static int rmargin = (int)(appResources.winW * 0.15);
  262.     CredFont *credFont;
  263.     char imgFilename[80];
  264.     int xsize, ysize;
  265.     int xoff, yoff;
  266.     ulong *buf;
  267.  
  268.     for (int i = 0; i < CredSection::credSectCnt; i++)
  269.         delete credSects[i];
  270.  
  271.     CredSection::credSectCnt = 0;
  272.     CredSection::totalCredHeight = 0;
  273.     
  274.     // Read in credits file
  275.     // lines starting with ':' are directives for fonts, colors, images, etc.
  276.     // lines starting with '#' are comment lines
  277.     // all other lines are text lines
  278.     ifstream credFile( appResources.credFilename, ios::in ) ;
  279.     if ( !credFile ) {
  280.       cerr << "unable to open file for input" << endl;
  281.       exit(0);
  282.     }
  283.     char cname[80];
  284.     int red;
  285.     int green;
  286.     int blue;
  287.     while ( credFile.getline(lineStr, lineSize) ) {
  288.       switch (lineStr[0]) {
  289.         case ':':
  290.           sscanf(lineStr, "%*c %s", directive);
  291.       switch(getToken(directive)) {
  292.        case FONTCMD: 
  293.          sscanf(lineStr, "%*c %s %s %d %s %s %f %f", directive, 
  294.                                                fFamily, &fSize, fCname, 
  295.                                                fJust, &fAngle, &fSpacing);
  296.          fColor = fcolors.get(fCname) | 0xFF000000;
  297.          credSects[CredSection::credSectCnt] = new CredFont(fFamily,
  298.                                                 fSize, fColor, fJust,
  299.                             fAngle, fSpacing);
  300.          credSects[CredSection::credSectCnt]->credType = FontTypeId;
  301.          credSects[CredSection::credSectCnt]->setLMargin(lmargin);
  302.          credSects[CredSection::credSectCnt]->setRMargin(rmargin);
  303.          CredSection::credSectCnt++;
  304.              if (appResources.debug)
  305.            cout << "fontFamily = " << fFamily << " size = " << fSize << endl;
  306.          break;
  307.        case IMAGECMD:
  308.          sscanf(lineStr, "%*c %s %s %d %d", directive, imgFilename, &xoff, 
  309.                 &yoff);
  310.          readImage(imgFilename, &xsize, &ysize, &buf);
  311.          tmpbuf = buf;
  312.          credSects[CredSection::credSectCnt] = new CredImage(xoff, yoff, 
  313.                                                              xsize - 1, 
  314.                                                              ysize - 1, buf);
  315.          credSects[CredSection::credSectCnt]->credType = ImageTypeId;
  316.          credSects[CredSection::credSectCnt]->credCnt++;
  317.          CredSection::credSectCnt++;
  318.          break;
  319.        case COLORCMD:
  320.          sscanf(lineStr, "%*c %s %d %d %d %s", directive, 
  321.                                            &red, &green, &blue, cname);
  322.              if (appResources.debug)
  323.            cout << "color " << cname << " defined" << endl;
  324.          fcolors.add(red, green, blue, cname);
  325.          break;
  326.        case LMARGINCMD:
  327.          sscanf(lineStr, "%*c %s %d", directive, &lmargin);
  328.              if (appResources.debug)
  329.            cout << "LMARGIN set to " << lmargin << endl;
  330.          break;
  331.        case RMARGINCMD:
  332.          sscanf(lineStr, "%*c %s %d", directive, &rmargin);
  333.          break;
  334.        case BGCOLCMD:
  335.          sscanf(lineStr, "%*c %s %d", directive, &bgcol);
  336.          break;
  337.        }
  338.        break;
  339.          case '#': break;
  340.      default: 
  341.        credFont = (CredFont *)credSects[CredSection::credSectCnt - 1];
  342.            credFont->addStr(lineStr);
  343.        break;
  344.       }
  345.     }
  346.     credFile.close();
  347.     cout << "projected time to scroll: " << (CredSection::totalCredHeight + 
  348.        appResources.winH) / (appResources.fps * appResources.speed) << " secs"
  349.        << endl;
  350. }
  351.  
  352.  
  353. static void
  354. updateStatBar(float perf)
  355. {
  356.   static short zoneLen = 120;
  357.  
  358.     cpack(0x00FF00);
  359.     rectfs(0, appResources.winH, zoneLen, appResources.winH - 40);
  360.     cpack(0x00FFFF);
  361.     rectfs(zoneLen + 1, appResources.winH, zoneLen * 2, appResources.winH - 40);
  362.     if (dropped)
  363.       cpack(0x0000FF);
  364.     else
  365.       cpack(0xFF0000);
  366.     rectfs(0, appResources.winH - 10, (short)(ceilf((appResources.fps/(1/perf))
  367.            * zoneLen)), appResources.winH - 30);
  368. }
  369.  
  370.  
  371. void
  372. initText()
  373. {
  374.     wfm_init();
  375.     wfm_hint(FONTHINT_ROUNDADVANCE, 0);
  376.     wfm_hint(FONTHINT_SCALETHRESH, 40);
  377.     wfm_hint(FONTHINT_MINOUTLINESIZE, 20);
  378.     wfm_hint(FONTHINT_AABITMAPFONTS, 0);
  379.     wfm_hint(FONTHINT_SCALETHRESH, 10);
  380.     wfm_hint(FONTHINT_MAXAASIZE, 200);
  381.     wfm_aacpack(0xFF000000, 0xB0000000);
  382. }
  383.  
  384.  
  385. void
  386. scrollCreds(XtPointer, ulong *)
  387. {
  388.     short xpos = 0;
  389.     short ypos = 0;
  390.     int leading;
  391.     int credYoff = 0;
  392.     static int credPosY = 0;
  393.     static int credUpdateY = 0;
  394.     static float gfxIntvl = 0;
  395.     static int nframes = 0;
  396.  
  397.     if (appResources.debug)
  398.       timerPerf->startTiming();
  399.  
  400.     if (restart) {
  401.         credPosY = 0;
  402.         credUpdateY =0;
  403.         restart = False;
  404.     }
  405.             
  406.     credUpdateY = appResources.speed * direction;
  407.     cpack(fcolors.get("black"));
  408.     clear();
  409.     for ( int j = 0; j < CredSection::credSectCnt; j++ ) {
  410.       leading = (int)(credSects[j]->size * credSects[j]->spacing);
  411.       for ( int k = 0; k < credSects[j]->credCnt; k++) {
  412.         xpos = credSects[j]->image[k].xpos + credSects[j]->xoff;
  413.         ypos = credPosY - credYoff - ((k + 1) * leading) + credSects[j]->yoff;
  414.         if (ypos > -credSects[j]->size && ypos < appResources.winH)
  415.           if ((ypos - appResources.speed) > 0  && ypos < appResources.winH 
  416.                && !refresh)
  417.             rectcopy(xpos, credSects[j]->image[k].lastY, 
  418.                      xpos + credSects[j]->image[k].width,
  419.                      credSects[j]->image[k].lastY + 
  420.              credSects[j]->image[k].height,
  421.                      xpos, ypos);
  422.           else
  423.             lrectwrite(xpos, ypos, xpos + credSects[j]->image[k].width, 
  424.                     ypos + credSects[j]->image[k].height, 
  425.                     credSects[j]->image[k].imgBuf);
  426.         credSects[j]->image[k].lastY = ypos;
  427.        }
  428.        credYoff += credSects[j]->credCnt * leading;
  429.      }
  430.      refresh = False;
  431.      credPosY += credUpdateY;
  432.      if (ypos > appResources.winH) {
  433.        credPosY = 0;
  434.        float fr = frameRatePerf->getInterval();
  435.        if (appResources.perf)
  436.          cout << swapCnt << " frames during " << fr << " secs, " << 
  437.            floorf(appResources.fps * fr) - swapCnt << " frames dropped" << endl;
  438.        frameRatePerf->startTiming();
  439.        swapCnt = 0;
  440.      }
  441.      if (appResources.perf)
  442.        updateStatBar(gfxIntvl);
  443.      finish();
  444.      if (appResources.perf)
  445.        gfxIntvl = timerPerf->getInterval();
  446. }
  447.  
  448.  
  449. void
  450. swapGfx()
  451. {
  452.   swapbuffers();
  453.   swapCnt++;
  454. }
  455.  
  456.  
  457. void
  458. updateGfx()
  459. {
  460.   XEvent event;   
  461.   static int refreshes = 0;
  462.   XtInputMask mask;
  463.   if (credMotion) {
  464.     scrollCreds((XtPointer)0, (ulong *)0);
  465.     swapGfx();
  466.     if (mask = XtAppPending(app_context)) {
  467.        XtAppProcessEvent(app_context, mask);
  468.     }
  469.   }
  470.   else {
  471.     XtAppNextEvent(app_context, &event);
  472.     XtDispatchEvent(&event);
  473.   }
  474. }
  475.  
  476.  
  477. main(int argc, char **argv)
  478. {
  479.     XEvent event;
  480.     
  481.     createInterface(&argc, argv);
  482.     setProcessPriority();    
  483.  
  484. //    initVideo(toplevel);
  485.  
  486.     readCreditsFile();    
  487.     initText();
  488.       
  489.     XtAddCallback(glw, GlxNexposeCallback, grabTextBlocks, 0);
  490.  
  491.     while (!gfxSetupComplete) {
  492.       XtAppNextEvent(app_context, &event);
  493.       XtDispatchEvent(&event);
  494.     }
  495.  
  496.     while(1)
  497.       updateGfx();
  498. }
  499.